home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 June
/
CHIP Haziran 2001.iso
/
prog
/
haziran
/
19
/
setup.exe
/
data.z
/
p9050_serial.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-04-11
|
6KB
|
169 lines
////////////////////////////////////////////////////////////////
// File - P9050_SERIAL.C
//
// This is a serial port driver for PLX 9050 RDK board.
//
// To use this driver, install the PLX 9050 RDK board, plug in
// to the piggyback ISA connector the serial port or modem ISA
// card. Run this driver.
// Your ISA serial port will be detected, and written into the
// registry. After rebooting, a new COM port will be added, that
// will allow you to access your legacy ISA card.
//
////////////////////////////////////////////////////////////////
#include <windows.h>
#include <winioctl.h>
#include "../../../include/windrvr.h"
#include "../lib/p9050_lib.c"
#include <stdio.h>
CHAR *sApp = "PLX 9050 Serial Driver";
DWORD PLX_DetectInterrupt(P9050_HANDLE hPlx, DWORD dwVendorID, DWORD dwDeviceID, DWORD nCardNum)
{
WD_PCI_SCAN_CARDS pciScan;
WD_PCI_CARD_INFO pciCardInfo;
DWORD i;
BZERO(pciScan);
pciScan.searchId.dwVendorId = dwVendorID;
pciScan.searchId.dwDeviceId = dwDeviceID;
WD_PciScanCards (hPlx->hWD, &pciScan);
if (pciScan.dwCards<=nCardNum)
return 0; // no cards found
BZERO(pciCardInfo);
pciCardInfo.pciSlot = pciScan.cardSlot[nCardNum];
WD_PciGetCardInfo (hPlx->hWD, &pciCardInfo);
// search for interrupt item
for (i=0; i<pciCardInfo.Card.dwItems; i++)
{
if (pciCardInfo.Card.Item[i].item==ITEM_INTERRUPT)
return pciCardInfo.Card.Item[i].I.Int.dwInterrupt;
}
return 0; // interrupt not found
}
// The main window loop.
// WinMain() opens a handle for speaker, and then creates the main menu window.
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
{
// IO addresses of serial ports on the local bus attached to the PLX 9050 board
DWORD dwSerialAddr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8, 0xffffffff};
// start creating com ports from COM5
DWORD dwComPort = 5;
P9050_HANDLE hPlx = NULL;
DWORD dwVendorID = 0x10b5;
DWORD dwDeviceID = 0x9050;
DWORD nCardNum = 0; // use this if you have more than one plx 9050 boards installed.
DWORD dwInterrupt;
DWORD res;
DWORD val;
CHAR sTmp[256];
DWORD i;
OSVERSIONINFO lVerInfo;
HKEY hKey;
DWORD dwFound = 0;
int retVal = FALSE;
lVerInfo.dwOSVersionInfoSize = sizeof (lVerInfo);
GetVersionEx (&lVerInfo);
switch (lVerInfo.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
break;
case VER_PLATFORM_WIN32_WINDOWS:
default:
MessageBox( NULL, "This driver will only work on Windows NT\n", sApp, MB_OK | MB_ICONERROR );
goto Exit;
}
// open PLX 9050 card WITHOUT interrupts.
// sometimes there might be problems with interrupt sharing
if (!P9050_Open( &hPlx, dwVendorID, dwDeviceID, nCardNum, 0))
{
MessageBox( NULL, P9050_ErrorString, sApp, MB_OK | MB_ICONERROR );
goto Exit;
}
// since we opened the card without interrupts, then we have to fetch
// the interrupt information ourselves
dwInterrupt = PLX_DetectInterrupt(hPlx, dwVendorID, dwDeviceID, nCardNum);
if (!dwInterrupt)
{
MessageBox( NULL, "No interrupt allocated for card\n", sApp, MB_OK | MB_ICONERROR );
goto Exit;
}
// the standard serial port can only access IO mapped devices
if (hPlx->addrDesc[P9050_ADDR_SPACE1].fIsMemory)
{
MessageBox( NULL, "Address space 1 (BAR3) must be IO mapped in order that the standard serial driver can access it\n",
sApp, MB_OK | MB_ICONERROR );
goto Exit;
}
// Sanity check: is address space 1 mapped 0x0-0x3ff IO range.
// If your plx device is configured differently, then you can adjust this test
// to the size you programmed address space 1.
if (hPlx->addrDesc[P9050_ADDR_SPACE1].dwBytes != 0x400)
{
MessageBox( NULL, "Expected address space 1 (BAR3) to be of size 0x400\n", sApp, MB_OK | MB_ICONERROR );
goto Exit;
}
// test the PLX 9050 local bus for serial ports
for (i=0; dwSerialAddr[i]!=0xffffffff; i++)
{
DWORD dwAddr = dwSerialAddr[i];
DWORD dwVal0, dwVal1, dwVal2;
// Validation: is there a serial port at this address?
dwVal0 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr);
dwVal1 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr+1);
dwVal2 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr+2);
if (dwVal0 == dwVal1 && dwVal1==dwVal2)
{
//printf ("all registers have the same values - this is probably not a serial port\n");
continue;
}
sprintf (sTmp,"System\\CurrentControlSet\\Services\\Serial\\Parameters\\Serial%d", dwComPort+dwFound-1);
RegCreateKeyEx (HKEY_LOCAL_MACHINE, sTmp, 0,"",0,KEY_ALL_ACCESS, NULL, &hKey, &res);
sprintf (sTmp, "COM%d", dwComPort+dwFound);
RegSetValueEx (hKey, "DosDevices", 0, REG_SZ, sTmp, strlen(sTmp)+1);
val = 1;
RegSetValueEx (hKey, "ForceFifoEnable", 0, REG_DWORD, (PVOID) &val, 4);
val = dwInterrupt;
RegSetValueEx (hKey, "Interrupt", 0, REG_DWORD, (PVOID) &val, 4);
val = hPlx->addrDesc[P9050_ADDR_SPACE1].dwAddr + dwAddr;
RegSetValueEx (hKey, "PortAddress", 0, REG_DWORD, (PVOID) &val, 4);
RegCloseKey (hKey);
dwFound ++;
}
if (dwFound)
{
retVal = TRUE;
sprintf (sTmp, "%d serial ports were found on the PLX 9050 board.\n"
"You will need to reboot in order for the serial driver to be activated.",
dwFound);
MessageBox( NULL, sTmp, sApp, MB_OK);
}
else
MessageBox( NULL, "No serial ports found on the PLX 9050 board\n", sApp, MB_OK | MB_ICONERROR );
Exit:
if (hPlx)
P9050_Close( hPlx);
return retVal;
}